package com.atguigu.tingshu.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.account.AccountFeignClient;
import com.atguigu.tingshu.album.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AlbumInfoFeignClient albumFeignClient;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderDerateMapper orderDerateMapper;

    @Autowired
    private AccountFeignClient accountFeignClient;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 订单结算页面渲染-数据汇总
     * 1.处理购买类型-VIP会员
     * 2.处理购买类型-专辑
     * 3.处理购买类型-声音
     *
     * @return
     */
    @Override
    public OrderInfoVo trade(Long userId, TradeVo tradeVo) {
        //1.声明订单结算对象中价格变量，订单明细、优惠信息变量-赋予初始值
        BigDecimal originalAmount = new BigDecimal("0.00");
        BigDecimal derateAmount = new BigDecimal("0.00");
        BigDecimal orderAmount = new BigDecimal("0.00");
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();
        //2.远程调用用户微服务获取用户信息
        UserInfoVo userInfoVo = userFeignClient.getUserInfoVoByUserId(userId).getData();
        Assert.notNull(userInfoVo, "用户信息为空，请联系管理员");

        //3.处理购买类型-VIP会员
        if (SystemConstant.ORDER_ITEM_TYPE_VIP.equals(tradeVo.getItemType())) {
            //3.1 远程调用“用户服务”获取 根据VIP套餐ID查询套餐信息
            VipServiceConfig vipServiceConfig = userFeignClient.getVipServiceConfig(tradeVo.getItemId()).getData();
            Assert.notNull(vipServiceConfig, "VIP套餐不存在，请联系管理员");
            //3.2 动态计算VIP会员价格：原价、订单价、减免价
            originalAmount = vipServiceConfig.getPrice();
            orderAmount = vipServiceConfig.getDiscountPrice();
            derateAmount = originalAmount.subtract(orderAmount);

            //3.3 封装订单明细集合（VIP套餐信息）
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemName(vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            //设置原价
            orderDetailVo.setItemPrice(originalAmount);
            orderDetailVoList.add(orderDetailVo);

            //3.4 封装订单优惠集合（VIP优惠信息）
            OrderDerateVo orderDerateVo = new OrderDerateVo();
            orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
            orderDerateVo.setDerateAmount(derateAmount);
            orderDerateVo.setRemarks("VIP折扣价：" + derateAmount);
            orderDerateVoList.add(orderDerateVo);

        } else if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(tradeVo.getItemType())) {
            //4.处理购买类型-专辑
            //4.1 远程调用“用户服务”判断用户是否已购买该专辑
            Boolean ifBuy = userFeignClient.isPaidAlbum(tradeVo.getItemId()).getData();
            if (ifBuy) {
                throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
            }
            //4.2 远程调用“专辑服务”获取专辑信息
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(tradeVo.getItemId()).getData();
            Assert.notNull(albumInfo, "专辑不存在！");
            //4.3 动态计算专辑价格：原价、订单价、减免价
            originalAmount = albumInfo.getPrice();
            orderAmount = originalAmount;
            if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(DateUtil.date())) {
                if (albumInfo.getVipDiscount().intValue() != -1) {
                    //当前用户是VIP用户
                    orderAmount = originalAmount.multiply(albumInfo.getVipDiscount()).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                    //减免价格=原价-订单价格
                    derateAmount = originalAmount.subtract(orderAmount);
                }
            } else {
                if (albumInfo.getDiscount().intValue() != -1) {
                    //普通用户折扣 订单价=原价*8/10
                    orderAmount = originalAmount.multiply(albumInfo.getDiscount()).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                    //减免价格=原价-订单价格
                    derateAmount = originalAmount.subtract(orderAmount);
                }
            }
            //4.4 封装订单明细集合（专辑信息）
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemName(albumInfo.getAlbumTitle());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemPrice(originalAmount);
            orderDetailVoList.add(orderDetailVo);

            //4.5 封装订单优惠集合（优惠信息）
            OrderDerateVo orderDerateVo = new OrderDerateVo();
            orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
            orderDerateVo.setDerateAmount(derateAmount);
            orderDerateVo.setRemarks("专辑优惠：" + derateAmount);
            orderDerateVoList.add(orderDerateVo);
        } else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(tradeVo.getItemType())) {
            //5.TODO 处理购买类型-声音
            //5.1 远程调用“专辑服务”-根据选择声音ID+数量得到待购声音列表（将已购声音排除掉）
            List<TrackInfo> waitPayTrackInfoList = albumFeignClient.getWaitPayTrackInfoList(tradeVo.getItemId(), tradeVo.getTrackCount()).getData();

            //5.2 远程调用"专辑服务"获取专辑信息-得到声音单价
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(waitPayTrackInfoList.get(0).getAlbumId()).getData();

            BigDecimal price = albumInfo.getPrice();

            //5.3 计算价格：原价，订单价 声音不支持折扣
            originalAmount = price.multiply(BigDecimal.valueOf(waitPayTrackInfoList.size())).setScale(2, RoundingMode.HALF_UP);
            orderAmount = originalAmount;

            //5.4 遍历待购声音列表构建订单明细集合
            orderDetailVoList = waitPayTrackInfoList.stream().map(trackInfo -> {
                OrderDetailVo orderDetailVo = new OrderDetailVo();
                orderDetailVo.setItemId(trackInfo.getId());
                orderDetailVo.setItemName(trackInfo.getTrackTitle());
                orderDetailVo.setItemUrl(trackInfo.getCoverUrl());
                orderDetailVo.setItemPrice(price);
                return orderDetailVo;
            }).collect(Collectors.toList());
        }
        //6.构建渲染订单结算所需对象OrderInfoVo：包含价格、订单明细列表、优惠列表、其他属性
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        //6.1 针对本次请求产生流水号，订单被重复条件（提交后回退到页面后继续提交） 将流水存入Redis，方便后续提交订单验证流水号
        String tradeKey = RedisConstant.ORDER_TRADE_NO_PREFIX + userId;
        String tradeNo = IdUtil.fastSimpleUUID();
        redisTemplate.opsForValue().set(tradeKey, tradeNo, 5, TimeUnit.MINUTES);
        orderInfoVo.setTradeNo(tradeNo);
        orderInfoVo.setItemType(tradeVo.getItemType());
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        //6.2 针对本次请求所有参数进行签名 --->md5（参数）=签名值 防止数据被网络传输过程中被恶意篡改
        orderInfoVo.setTimestamp(DateUtil.current());
        //将Bean对象转为Map 将对象中空值排除掉：支付类型"payway"
        Map<String, Object> map = BeanUtil.beanToMap(orderInfoVo, false, true);
        String sign = SignHelper.getSign(map);
        orderInfoVo.setSign(sign);
        return orderInfoVo;
    }

    /**
     * 订单提交及可能存在余额支付
     *
     * @param orderInfoVo
     * @return
     */
    @Override
//    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public Map<String, String> submitOrder(Long userId, OrderInfoVo orderInfoVo) {
        //1.请求参数验签-避免提交参数被篡改
        //1.1 当时渲染结算页签名生成将支付方式payWay排除，提交VO中包含支付方式，在验签前将VO转为Map将支付方式“payWay”移除
        Map<String, Object> paramMap = BeanUtil.beanToMap(orderInfoVo);
        paramMap.remove("payWay");
        //1.2 调用工具方法验证签名
        SignHelper.checkSign(paramMap);

        //2.验证流水号-避免订单重复提交
        //2.1 先通过流水号Key查询Redis中正确流水号
        String tradeKey = RedisConstant.ORDER_TRADE_NO_PREFIX + userId;
        //2.2 跟用户提交流水号比对 比对成功后，将流水号删除（保证原子性-lua脚本）
        String script = "if(redis.call('get', KEYS[1]) == ARGV[1]) then return redis.call('del', KEYS[1]) else return 0 end";
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(script);
        redisScript.setResultType(Boolean.class);
        Boolean flag = (Boolean) redisTemplate.execute(redisScript, Arrays.asList(tradeKey), orderInfoVo.getTradeNo());
        if (!flag) {
            throw new GuiguException(ResultCodeEnum.ORDER_SUBMIT_REPEAT);
        }
        //3.保存订单及订单明细、订单优惠明细
        OrderInfo orderInfo = this.saveOrder(userId, orderInfoVo);

        //4.TODO 处理余额付款（支付方式：1101-微信 1102-支付宝 1103-账户余额） VIP、专辑、声音都支持余额付款。声音仅自持余额付款
        if (SystemConstant.ORDER_PAY_ACCOUNT.equals(orderInfoVo.getPayWay())) {

            try {
                //4.1 远程调用“账户微服务”-检查及锁定可用余额
                AccountLockVo accountLockVo = new AccountLockVo();
                accountLockVo.setOrderNo(orderInfo.getOrderNo());
                accountLockVo.setUserId(userId);
                accountLockVo.setAmount(orderInfoVo.getOrderAmount());
                accountLockVo.setContent(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
                Result<AccountLockResultVo> lockResult = accountFeignClient.checkAndLock(accountLockVo);
                if (200 != lockResult.getCode() || lockResult.getData() == null) {
                    log.error("[订单服务]远程调用账户服务进行锁定可用余额失败:业务状态码：{},信息：{}", lockResult.getCode(), lockResult.getMessage());
                    String xid = RootContext.getXID();
                    if (xid != null) {
                        try {
                            // 手动回滚全局事务
                            GlobalTransactionContext.reload(xid).rollback();
                        } catch (TransactionException ex) {
                            ex.printStackTrace();
                        }
                    }
                    //锁定金额异常，订单也必须回滚
                    throw new GuiguException(lockResult.getCode(), lockResult.getMessage());
                }

                //4.2 TODO 锁定成功：默认扣减为成功 采用MQ完成账户扣减
                kafkaService.sendMessage(KafkaConstant.QUEUE_ACCOUNT_MINUS, orderInfo.getOrderNo());

                //4.3 TODO 修改订单状态：修改为已支付
                orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
                orderInfoMapper.updateById(orderInfo);

                //4.4 TODO 采用MQ处理用户购买记录
                UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
                userPaidRecordVo.setOrderNo(orderInfo.getOrderNo());
                userPaidRecordVo.setUserId(userId);
                userPaidRecordVo.setItemType(orderInfoVo.getItemType());
                List<Long> itemIdList = orderInfoVo.getOrderDetailVoList().stream().map(OrderDetailVo::getItemId).collect(Collectors.toList());
                userPaidRecordVo.setItemIdList(itemIdList);
                kafkaService.sendMessage(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));

            } catch (Exception e) {
                //4.5 TODO 如果以上操作异常，采用MQ完成账户回滚
                //以上操作：锁定、扣减、购买记录等业务代码异常 则进行基于MQ消息进行回滚
                //5.利用kafka消息完成解锁
                kafkaService.sendMessage(KafkaConstant.QUEUE_ACCOUNT_UNLOCK, orderInfo.getOrderNo());
                //TODO 利用Kafka消息完成购买记录回滚（删除）达到事务最终一致
                throw new RuntimeException(e.getMessage());
            }

        }
        //5.封装订单编号到Map
        Map<String, String> map = new HashMap<>();
        map.put("orderNo", orderInfo.getOrderNo());

        //6.TODO 发送延迟消息：延迟关闭订单
        this.sendDelayMessage(orderInfo.getId());
        return map;
    }

    @Override
    public OrderInfo saveOrder(Long userId, OrderInfoVo orderInfoVo) {
        //1.将订单相关信息封装为订单对象，向订单表增加一条记录
        //1.1 将入参订单VO拷贝到订单PO对象中
        OrderInfo orderInfo = BeanUtil.copyProperties(orderInfoVo, OrderInfo.class);
        //设置未赋值的属性:订单标题、用户id、订单编号、订单状态
        orderInfo.setUserId(userId);
        orderInfo.setOrderTitle(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
        //订单编号形式：当天YYYYMMDD+分布式ID生成策略：雪花算法
        String orderNo = DateUtil.today().replaceAll("-", "") + IdUtil.getSnowflakeNextId();
        orderInfo.setOrderNo(orderNo);
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_UNPAID);
        orderInfoMapper.insert(orderInfo);
        Long orderId = orderInfo.getId();

        // 2.将提交订单明细封装为订单明细集合，批量向订单明细表新增若干条记录
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        if (CollectionUtil.isNotEmpty(orderDetailVoList)) {
            orderDetailVoList.stream().forEach(orderDetailVo -> {
                OrderDetail orderDetail = BeanUtil.copyProperties(orderDetailVo, OrderDetail.class);
                orderDetail.setOrderId(orderId);
                orderDetailMapper.insert(orderDetail);
            });
        }

        //3.将提交优惠明细封装为优惠明细集合，批量向优惠明细表新增若干条记录
        List<OrderDerateVo> orderDerateVoList = orderInfoVo.getOrderDerateVoList();
        if (CollectionUtil.isNotEmpty(orderDerateVoList)) {
            orderDerateVoList.stream().forEach(orderDerateVo -> {
                OrderDerate orderDerate = BeanUtil.copyProperties(orderDerateVo, OrderDerate.class);
                orderDerate.setOrderId(orderId);
                orderDerateMapper.insert(orderDerate);
            });
        }
        return orderInfo;

    }



    /**
     * 发送延迟消息
     */
    private void sendDelayMessage(Long orderId) {
        try {
            //  创建一个队列
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(KafkaConstant.QUEUE_ORDER_CANCEL);
            //  将队列放入延迟队列中
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            //  发送的内容
            delayedQueue.offer(orderId.toString(), KafkaConstant.DELAY_TIME, TimeUnit.SECONDS);
            log.info("添加延时队列成功 ，延迟时间：{}，订单id：{}", KafkaConstant.DELAY_TIME, orderId);
        } catch (Exception e) {
            log.error("添加延时队列失败 ，延迟时间：{}，订单id：{}", KafkaConstant.DELAY_TIME, orderId);
            e.printStackTrace();
        }
    }

    /**
     * 获取订单信息
     *
     * @param userId
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getOrderInfo(Long userId, String orderNo) {
        //1.根据订单编号+用户ID查询订单信息
        LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderInfo::getOrderNo, orderNo);
        queryWrapper.eq(OrderInfo::getUserId, userId);
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        if (orderInfo != null) {
            //2.根据订单ID查询订单明细
            LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderInfo.getId());
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(orderDetailLambdaQueryWrapper);
            orderInfo.setOrderDetailList(orderDetailList);
            orderInfo.setPayWayName(this.getPayWayName(orderInfo.getPayWay()));
            orderInfo.setOrderStatusName(this.getOrderStatusName(orderInfo.getOrderStatus()));
            //3.根据订单ID查询订单优惠明细
            LambdaQueryWrapper<OrderDerate> orderDerateLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderDerateLambdaQueryWrapper.eq(OrderDerate::getOrderId, orderInfo.getId());
            List<OrderDerate> orderDerateList = orderDerateMapper.selectList(orderDerateLambdaQueryWrapper);
            orderInfo.setOrderDerateList(orderDerateList);
            return orderInfo;
        }
        return null;
    }

    /**
     * 分页获取用户订单列表
     *
     * @param pageInfo
     * @param userId
     * @return
     */
    @Override
    public Page<OrderInfo> getUserOrderByPage(Page<OrderInfo> pageInfo, Long userId) {
        pageInfo = orderInfoMapper.getUserOrderByPage(pageInfo, userId);
        //设置订单状态跟支付方式：中文
        pageInfo.getRecords().forEach(orderInfo -> {
            orderInfo.setOrderStatusName(this.getOrderStatusName(orderInfo.getOrderStatus()));
            orderInfo.setPayWayName(this.getPayWayName(orderInfo.getPayWay()));
        });
        return pageInfo;
    }

    @Override
    public void orderCancel(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (SystemConstant.ORDER_STATUS_UNPAID.equals(orderInfo.getOrderStatus())) {
            OrderInfo orderInfoUpt = new OrderInfo();
            orderInfoUpt.setId(orderId);
            orderInfoUpt.setOrderStatus(SystemConstant.ORDER_STATUS_CANCEL);
            this.updateById(orderInfoUpt);
        }
    }

    /**
     * 更新订单状态：已支付、基于MQ异步新增用户购买记录
     *
     * @param orderNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPaySuccess(String orderNo) {
        //1.根据订单编号查询订单信息，更新订单状态：已支付（幂等性）
        OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
        orderInfoMapper.updateById(orderInfo);

        //2.发送MQ消息通知“用户服务”新增用户购买记录 UserPaidRecordVo
        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        userPaidRecordVo.setOrderNo(orderNo);
        userPaidRecordVo.setUserId(orderInfo.getUserId());
        userPaidRecordVo.setItemType(orderInfo.getItemType());
        //获取订单明细 封装用户购买项ID集合
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderInfo.getId()));
        if(CollectionUtil.isNotEmpty(orderDetailList)){
            List<Long> itemIdList = orderDetailList.stream().map(OrderDetail::getItemId).collect(Collectors.toList());
            userPaidRecordVo.setItemIdList(itemIdList);
            kafkaService.sendMessage(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));
        }
    }

    private String getOrderStatusName(String orderStatus) {
        if (SystemConstant.ORDER_STATUS_UNPAID.equals(orderStatus)) {
            return "未支付";
        } else if (SystemConstant.ORDER_STATUS_PAID.equals(orderStatus)) {
            return "已支付";
        } else if (SystemConstant.ORDER_STATUS_CANCEL.equals(orderStatus)) {
            return "取消";
        }
        return null;
    }

    /**
     * 根据支付方式编号得到支付名称
     *
     * @param payWay
     * @return
     */
    private String getPayWayName(String payWay) {
        if (SystemConstant.ORDER_PAY_WAY_WEIXIN.equals(payWay)) {
            return "微信";
        } else if (SystemConstant.ORDER_PAY_ACCOUNT.equals(payWay)) {
            return "余额";
        } else if (SystemConstant.ORDER_PAY_WAY_ALIPAY.equals(payWay)) {
            return "支付宝";
        }
        return "";
    }


    public static void main(String[] args) {
        //价格方式: 一、浮点型 BigDesimal 单位:元 二、Long 单位:分
        //一、建议一定优先使用 字符串 入参
        BigDecimal bigDecimal = new BigDecimal("0.1");
        BigDecimal bigDecimal1 = new BigDecimal(0.1);//直接传入数字，会丢失精度
        //valueof方法 不能超过Double最大值 超过以后会出现精度问题
        BigDecimal bigDecimal2 = BigDecimal.valueOf(0.1);
        System.out.println(bigDecimal);
        System.out.println(bigDecimal1);//精度问题
        System.out.println(bigDecimal2);

        //二、比较两个大小 推荐使用: compareTo -1 0 1
        BigDecimal bigDecimalA = new BigDecimal("1");
        BigDecimal bigDecimalB = new BigDecimal("3");
        BigDecimal bigDecimalC = new BigDecimal("3.0");
        System.out.println("使用==" + (bigDecimalA == bigDecimalC));
        System.out.println("使用equals" + bigDecimalA.equals(bigDecimalB));
        System.out.println("使用compareTo" + bigDecimalA.compareTo(bigDecimalB));
        System.out.println("使用compareTo" + bigDecimalB.compareTo(bigDecimalC));

        //三、 相除 设置保留小数位
        BigDecimal bigDecimalA1 = new BigDecimal("1");
        BigDecimal bigDecimalB1 = new BigDecimal("3");
        BigDecimal divide = bigDecimalA1.divide(bigDecimalB1, 2, RoundingMode.HALF_UP);
        System.out.println("相除" + divide);
        //四、 相乘 设置保留小数位
        BigDecimal bigDecimalA2 = new BigDecimal("0.31");
        BigDecimal bigDecimalB2 = new BigDecimal("0.53");
        BigDecimal divide2 = bigDecimalA2.multiply(bigDecimalB2).setScale(2, RoundingMode.HALF_UP);
        System.out.println("相乘" + divide2);
    }
}
